package com.frank.oj.manager;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.frank.model.entity.contest.Contest;
import com.frank.model.entity.discussion.Comment;
import com.frank.model.entity.discussion.Discussion;
import com.frank.model.entity.discussion.Reply;
import com.frank.model.entity.msg.MsgRemind;
import com.frank.model.entity.msg.UserSysNotice;
import com.frank.oj.common.exception.StatusFailException;
import com.frank.oj.model.vo.UserMsgVO;
import com.frank.oj.model.vo.UserUnreadMsgCountVO;
import com.frank.oj.service.entity.contest.ContestEntityService;
import com.frank.oj.service.entity.discussion.CommentEntityService;
import com.frank.oj.service.entity.discussion.DiscussionEntityService;
import com.frank.oj.service.entity.msg.MsgRemindEntityService;
import com.frank.oj.service.entity.msg.ReplyEntityService;
import com.frank.oj.service.entity.msg.UserSysNoticeEntityService;
import com.frank.oj.shiro.AccountProfile;
import org.apache.shiro.SecurityUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author frank
 * @Date 2024/1/25
 */
@Component
public class UserMessageManager {
    @Resource
    private MsgRemindEntityService msgRemindEntityService;
    @Resource
    private DiscussionEntityService discussionEntityService;
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private ContestEntityService contestEntityService;
    @Resource
    private CommentEntityService commentEntityService;
    @Resource
    private ReplyEntityService replyEntityService;
    @Resource
    private UserSysNoticeEntityService userSysNoticeEntityService;

    public UserUnreadMsgCountVO getUnreadMsgCount() {
        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        UserUnreadMsgCountVO userUnreadMsgCountVO = msgRemindEntityService.getUnreadMsgCount(userRole.getUid());
        if (userUnreadMsgCountVO == null) {
            userUnreadMsgCountVO = new UserUnreadMsgCountVO(0, 0, 0, 0, 0);
        }
        return userUnreadMsgCountVO;
    }

    @Deprecated
    public IPage<UserMsgVO> getLikeMsg(Integer limit, Integer currentPage) {
        if (currentPage == null || currentPage < 1) currentPage = 1;
        if (limit == null || limit < 1) limit = 5;

        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        return getUserMsgList(userRole.getUid(), "Like", limit, currentPage);
    }

    @Deprecated
    public IPage<UserMsgVO> getCommentMsg(Integer limit, Integer currentPage) {
        if (currentPage == null || currentPage < 1) currentPage = 1;
        if (limit == null || limit < 1) limit = 5;

        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        return getUserMsgList(userRole.getUid(), "Discuss", limit, currentPage);
    }

    @Deprecated
    public IPage<UserMsgVO> getReplyMsg(Integer limit, Integer currentPage) {
        if (currentPage == null || currentPage < 1) currentPage = 1;
        if (limit == null || limit < 1) limit = 5;

        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        return getUserMsgList(userRole.getUid(), "Reply", limit, currentPage);

    }

    public IPage<UserMsgVO> getUserMsgList1(String action, Integer limit, Integer currentPage) {
        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        String uid = userRole.getUid();

        if (currentPage == null || currentPage < 1) currentPage = 1;
        if (limit == null || limit < 1) limit = 5;
        Page<UserMsgVO> page = new Page<>(currentPage, limit);

        IPage<UserMsgVO> userMsgList = msgRemindEntityService.getUserMsg(page, uid, action);

        if (userMsgList.getTotal() > 0) {
            switch (action) {
                case "Discuss":  // 评论我的
                    return getUserDiscussMsgList(userMsgList);
                case "Reply": // 回复我的
                    return getUserReplyMsgList(userMsgList);
                case "Like": //点赞
                    return getUserLikeMsgList(userMsgList);
                default:
                    throw new RuntimeException("invalid action:" + action);
            }
        } else {
            return userMsgList;
        }
    }

    @Deprecated
    private IPage<UserMsgVO> getUserMsgList(String uid, String action, Integer limit, Integer currentPage) {
        Page<UserMsgVO> page = new Page<>(currentPage, limit);
        IPage<UserMsgVO> userMsgList = msgRemindEntityService.getUserMsg(page, uid, action);

        if (userMsgList.getTotal() > 0) {
            switch (action) {
                case "Discuss":  // 评论我的
                    return getUserDiscussMsgList(userMsgList);
                case "Reply": // 回复我的
                    return getUserReplyMsgList(userMsgList);
                case "Like": //点赞
                    return getUserLikeMsgList(userMsgList);
                default:
                    throw new RuntimeException("invalid action:" + action);
            }
        } else {
            return userMsgList;
        }
    }

    /**
     * 获取点赞消息列表
     */
    private IPage<UserMsgVO> getUserLikeMsgList(IPage<UserMsgVO> userMsgList) {
        for (UserMsgVO userMsgVO : userMsgList.getRecords()) {
            if ("Discussion".equals(userMsgVO.getSourceType())) {
                Discussion discussion = discussionEntityService.getById(userMsgVO.getSourceId());
                if (discussion != null) {
                    userMsgVO.setSourceTitle(discussion.getTitle());
                } else {
                    userMsgVO.setSourceTitle("❌ 原帖已被删除！");
                }
            } else if ("Contest".equals(userMsgVO.getSourceType())) {
                Contest contest = contestEntityService.getById(userMsgVO.getSenderId());
                if (contest != null) {
                    userMsgVO.setSourceTitle(contest.getTitle());
                } else {
                    userMsgVO.setSourceTitle("❌ 原比赛已被删除！");
                }
            }
        }
        applicationContext.getBean(UserMessageManager.class).updateUserMsgRead(userMsgList);
        return userMsgList;
    }

    /**
     * 获取回复我的消息列表
     */
    private IPage<UserMsgVO> getUserReplyMsgList(IPage<UserMsgVO> userMsgList) {
        for (UserMsgVO userMsgVo : userMsgList.getRecords()) {
            if ("Discussion".equals(userMsgVo.getSourceType())) {
                Discussion discussion = discussionEntityService.getById(userMsgVo.getSourceId());
                if (discussion != null) {
                    userMsgVo.setSourceTitle(discussion.getTitle());
                } else {
                    userMsgVo.setSourceTitle("❌ 原帖已被删除！");
                }
            } else if ("Contest".equals(userMsgVo.getSourceType())) {
                Contest contest = contestEntityService.getById(userMsgVo.getSourceId());
                if (contest != null) {
                    userMsgVo.setSourceTitle(contest.getTitle());
                } else {
                    userMsgVo.setSourceTitle("❌ 原比赛已被删除！");
                }
            }

            // 评论
            if ("Comment".equals(userMsgVo.getQuoteType())) {
                Comment comment = commentEntityService.getById(userMsgVo.getQuoteId());
                if (comment != null) {
                    String content = null;
                    if (comment.getContent().length() < 100) {
                        content = comment.getFromName() + "：" + comment.getContent();
                    } else {
                        content = comment.getFromName() + "：" + comment.getContent().substring(0, 100) + "...";
                    }
                    userMsgVo.setQuoteContent(content);
                } else {
                    userMsgVo.setQuoteContent("❌ 原评论已被删除！");
                }
            } else if ("Reply".equals(userMsgVo.getQuoteType())) {
                Reply reply = replyEntityService.getById(userMsgVo.getQuoteId());
                if (reply != null) {
                    String content;
                    if (reply.getContent().length() < 100) {
                        content = reply.getFromName() + " : @" + reply.getToName() + "："
                                + reply.getContent();

                    } else {
                        content = reply.getFromName() + " : @" + reply.getToName() + "："
                                + reply.getContent().substring(0, 100) + "...";
                    }
                    userMsgVo.setQuoteContent(content);
                } else {
                    userMsgVo.setQuoteContent("❌ 您的原回复信息已被删除！");
                }
            }
        }
        applicationContext.getBean(UserMessageManager.class).updateUserMsgRead(userMsgList);
        return userMsgList;
    }

    /**
     * 获取评论我的消息列表
     */
    private IPage<UserMsgVO> getUserDiscussMsgList(IPage<UserMsgVO> userMsgList) {
        List<Integer> discussionIds = userMsgList.getRecords().stream()
                .map(UserMsgVO::getSourceId).collect(Collectors.toList());

        Collection<Discussion> discussions = discussionEntityService.listByIds(discussionIds);
        for (Discussion discussion : discussions) {
            for (UserMsgVO userMsgVO : userMsgList.getRecords()) {
                if (Objects.equals(discussion.getId(), userMsgVO.getSourceId())) {
                    userMsgVO.setSourceTitle(discussion.getTitle());
                    break;
                }
            }
        }
        applicationContext.getBean(UserMessageManager.class).updateUserMsgRead(userMsgList);
        return userMsgList;
    }

    /**
     * 更新消息为已读
     *
     * @param userMsgList 消息列表
     */
    @Async
    public void updateUserMsgRead(IPage<UserMsgVO> userMsgList) {
        List<Long> idList = userMsgList.getRecords().stream()
                .filter(userMsgVO -> !userMsgVO.getState()) // 未读消息
                .map(UserMsgVO::getId).collect(Collectors.toList());

        if (idList.isEmpty()) {
            return;
        }
        LambdaUpdateWrapper<MsgRemind> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(MsgRemind::getId, idList).set(MsgRemind::getState, true);

        msgRemindEntityService.update(null, updateWrapper);
    }


    public void cleanMsg(String type, Long id) throws StatusFailException {
        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        boolean isOk = cleanMsgByType(type, id, userRole.getUid());
        if (!isOk) {
            throw new StatusFailException("清除消息失败");
        }
    }

    private boolean cleanMsgByType(String type, Long id, String uid) {
        switch (type) {
            case "Like":
            case "Discuss":
            case "Reply":
                LambdaUpdateWrapper<MsgRemind> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(id != null, MsgRemind::getId, id) //有则单删，无则全删
                        .eq(MsgRemind::getRecipientId, uid); //接收人
                return msgRemindEntityService.remove(updateWrapper);
            case "Sys":
            case "Mine":
                LambdaUpdateWrapper<UserSysNotice> updateWrapper2 = new LambdaUpdateWrapper<>();
                updateWrapper2
                        .eq(id != null, UserSysNotice::getId, id)
                        .eq(UserSysNotice::getRecipientId, uid);
                return userSysNoticeEntityService.remove(updateWrapper2);
        }
        return false;
    }
}
